import 'dart:convert';

import 'package:dio/dio.dart';

enum DioMethod {
  get,
  post,
  put,
  delete,
}

const baseUrl='http://10.169.3.58:8090';

class DioManager {
  factory DioManager() => _getInstance();
  static DioManager? _instance;
  static DioManager _getInstance() {
    _instance ??= DioManager._init();
    return _instance!;
  }

  Dio? _dio;

  /// 初始化
  DioManager._init() {
    _dio ??= Dio(BaseOptions(
        // 请求基地址
        baseUrl: baseUrl,
        // 连接服务器超时时间，单位是毫秒
        connectTimeout: 10 * 1000,
        // 接收数据的最长时限
        receiveTimeout: 10 * 1000,
        // Http请求头
        headers: {
          'api': '1.0.0',
          'Accept':'application/json,*/*',
          'app':'app',
          'Content-Type':'application/json'
        }));
  }

  /// get请求
  Future get(
      {required String url, required Map<String, dynamic> params}) async {
    return await requestHttp(url, method: DioMethod.get, params: params);
  }

  /// post 请求
  Future post(
      {required String url, required Map<String, dynamic> params}) async {
    return await requestHttp(url, method: DioMethod.post, params: params);
  }

  /// put 请求
  Future put(
      {required String url, required Map<String, dynamic> params}) async {
    return await requestHttp(url, method: DioMethod.put, params: params);
  }

  /// delete 请求
  Future delete(
      {required String url, required Map<String, dynamic> params}) async {
    return await requestHttp(url, method: DioMethod.delete, params: params);
  }

  /// Dio request 方法
  Future requestHttp(String url,
      {DioMethod method = DioMethod.get,
      required Map<String, dynamic> params}) async {
    const methodValues = {
      DioMethod.get: 'get',
      DioMethod.post: 'post',
      DioMethod.delete: 'delete',
      DioMethod.put: 'put'
    };

    // 添加 token
    // TokenModel tokenModel = await SpUtil().loadToken();
    // if (tokenModel.userToken != null) {
    //   _dio.options.headers = {'Authorization': 'Bearer ' + tokenModel.userToken};
    // }
    _dio?.interceptors.add(InterceptorsWrapper(
        onRequest: (options, handler) => handler.next(options),
        onResponse: (response, handler) {
          handler.next(response);
        },
        onError: (err, handler) {
          handler.next(err);
        }));
    try {
      Response response;
      // 不同请求方法，不同的请求参数。按实际项目需求分，这里 get 是 queryParameters，其它用 data. FormData 也是 data
      // 注意: 只有 post 方法支持发送 FormData.
      switch (method) {
        case DioMethod.get:
          response = await _dio!.request(url,
              queryParameters: params,
              options: Options(method: methodValues[method]));
          break;
        default:
          response = await _dio!.request(url,
              data: params, options: Options(method: methodValues[method]));
      }

      // JSON 序列化, Response<dynamic> 转 Map<String, dynamic>
      String jsonStr = json.encode(response.data);
      Map<String, dynamic> map = json.decode(jsonStr);

      // PS: 取得 json 数据后, 只返回需要的数据，如果数据没有在外面包一层 BaseModel, 直接返回就可以。
      // var baseModel = BaseModel.fromJson(map);
      // return baseModel.data;
      return map;
    } on DioError catch (e) {
      throw e;
//      print('DioError--- ${e.type}');
      // 出现错误都返回空，错误在 OnErrorInterceptors 类处理。
    }
  }
}
